#include "Socket.hpp"
#include <poll.h>
#define DFL -1
#define NUM 1024
struct pollfd fdsArray[NUM];
static void showArray(struct pollfd arr[], int num)
{
    cout << "当前合法sock list# ";
    for (int i = 0; i < num; i++)
    {
        if (arr[i].fd == DFL)
            continue;
        else
            cout << arr[i].fd << " ";
    }
    cout << endl;
}
static void HandEvents(int listenSock)
{
    for (int i = 0; i < NUM; i++)
    {
        if (fdsArray[i].fd == DFL)
            continue;
        if (i == 0 && fdsArray[i].fd == listenSock && (fdsArray[i].revents & POLLIN))
        {
            cout << "有新的链接到来了，正在处理" << endl;
            string ip;
            uint16_t port;
            int sockfd = Sock::Accept(listenSock, &port, &ip);
            if (sockfd < 0)
                return;
            cout << "获取连接成功: [" << ip << ":" << port << "]sockfd:" << sockfd << endl;
            int index = 0;
            while (fdsArray[index].fd != DFL)
                ++index;
            if (index == NUM)
            {
                cout << "服务器已经达到了最大的连接上限了，无法维持更多的连接了。" << endl;
                close(sockfd);
            }
            else
            {
                fdsArray[index].fd = sockfd;
                fdsArray[index].events = POLLIN;
                fdsArray[index].revents = 0;
            }
            showArray(fdsArray, NUM);
        }
        else if (fdsArray[i].revents & POLLIN)
        {
            char buff[1024];
            ssize_t s = recv(fdsArray[i].fd, buff, sizeof(buff), 0);
            if (s > 0)
            {
                buff[s] = 0;
                cout << "client[" << fdsArray[i].fd << "]# " << buff << endl;
            }
            else
            {
                if(s==0)cout << "client[" << fdsArray[i].fd << "]quit,server close" <<endl;
                else cout << "client[" << fdsArray[i].fd << "]quit,server error" <<endl;
                close(fdsArray[i].fd);
                fdsArray[i].fd = DFL; // 去除对该文件描述符的select事件监听
                fdsArray[i].events = 0;
                fdsArray[i].revents = 0;
                showArray(fdsArray, NUM);
            }
        }
    }
}
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        cout << "Usage:\n\t" << argv[0] << " port" << endl;
        exit(-1);
    }
    int listenSock = Sock::Socket();
    Sock::Bind(listenSock, atoi(argv[1]));
    Sock::Listen(listenSock);

    for (int i = 0; i < NUM; i++)
    {
        fdsArray[i].fd = DFL;
        fdsArray[i].events = 0;
        fdsArray[i].revents = 0;
    }
    fdsArray[0].fd = listenSock;
    fdsArray[0].events = POLLIN;
    int timeout = -1; // 阻塞
    while (1)
    {
        int n = poll(fdsArray, NUM, timeout);
        switch (n)
        {
        case -1: 
            cerr<<errno<<" : "<<strerror(errno)<<endl;
            break;
        case 0:
            cout << "time out..." << endl;
            break;
        default:
            HandEvents(listenSock);
            break;
        }
    }

    return 0;
}